package tokens

import (
	"errors"
	"fmt"
	"strings"

	"gitee.com/botaoshow/yuanxin/web/common/conf"

	"github.com/golang-jwt/jwt/v4"
	"github.com/google/uuid"
)

type UserClaims struct {
	ShortToken string      `json:"short_token"`
	UserID     string      `json:"userId"`
	Data       interface{} `json:"data"`
	jwt.RegisteredClaims
}

func GenShortToken() string {
	return strings.ToUpper(strings.ReplaceAll(uuid.New().String(), "-", ""))
}

// GenToken 生成JWT
func GenToken(userID string, payloadData interface{}) (string, error) {
	token, _, err := GenToken2(userID, payloadData)
	return token, err
}

// GenToken2 带返回短token
func GenToken2(userID string, payloadData interface{}) (jwtToken string, shortToken string, err error) {
	genShortToken := GenShortToken()
	claims := UserClaims{
		ShortToken: genShortToken,
		UserID:     userID,
		Data:       payloadData,
		RegisteredClaims: jwt.RegisteredClaims{
			//ExpiresAt: jwt.NewNumericDate(time.Now().Add(48 * time.Hour)), // 过期时间设置为48小时
			Issuer: "jwt", // 签发人
		},
	}
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
	// 使用指定的secret签名并获得完整的编码后的字符串token
	signedString, err := token.SignedString([]byte(conf.AppConfig.Jwt.Secret))
	if err != nil {
		genShortToken = ""
	}
	return signedString, genShortToken, err
}

// ParseToken 解析JWT
func ParseToken(tokenString string) (*UserClaims, error) {
	var claims UserClaims
	// 解析token
	token, err := jwt.ParseWithClaims(tokenString, &claims, keyFunc)
	if err != nil {
		return nil, fmt.Errorf("parsing token: %w", err)
	}
	// 校验token
	if !token.Valid {
		return nil, errors.New("invalid token")
	}
	return &claims, nil
}

// keyFunc 定义获取密钥的函数
func keyFunc(_ *jwt.Token) (interface{}, error) {
	secret := conf.AppConfig.Jwt.Secret
	if secret == "" {
		secret = "123456"
	}
	return []byte(secret), nil
}
